package contabilidad;

import cuentasPagar.CRt100;
import java.awt.Color;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import utilitario.CCalculos;
import utilitario.CNumeros;

public class CTablaContable extends JTable {

    private String[] filaVacia;
    private modeloTablaContable modeloContable = null;
    int filaActual = -1;
    int columnaActual = -1;
    private CNumeros numero = null;
    private DefaultTableCellRenderer renderizadorAlineacion = null;
    private DefaultTableCellRenderer renderizadorColor = null;

    public CTablaContable(JTable tablaContable) {
        numero = new CNumeros();
        renderizadorAlineacion = new DefaultTableCellRenderer();
        renderizadorColor = new DefaultTableCellRenderer();
        renderizadorAlineacion.setHorizontalAlignment(SwingConstants.RIGHT);
        renderizadorColor.setForeground(Color.LIGHT_GRAY);
        filaVacia = new String[]{"", "", "", "", "", "", "", "", "", "AUTOMÁTICO", "", "", "S"};
        modeloContable = new modeloTablaContable();
        modeloContable.addColumn("N1");
        modeloContable.addColumn("N2");
        modeloContable.addColumn("N3");
        modeloContable.addColumn("N4");
        modeloContable.addColumn("N5");
        modeloContable.addColumn("DESCRIPCION");
        modeloContable.addColumn("CC1");
        modeloContable.addColumn("CC2");
        modeloContable.addColumn("CC3");
        modeloContable.addColumn("DESCRIPCION");
        modeloContable.addColumn("DEBITO");
        modeloContable.addColumn("CREDITO");
        modeloContable.addColumn("EDITABLE");
        tablaContable.setModel(modeloContable);
        TableColumn col = tablaContable.getColumnModel().getColumn(5);
        col.setPreferredWidth(400);
        col = tablaContable.getColumnModel().getColumn(9);
        col.setPreferredWidth(400);
        col.setCellRenderer(renderizadorColor);
        col = tablaContable.getColumnModel().getColumn(10);
        col.setPreferredWidth(100);
        col.setCellRenderer(renderizadorAlineacion);
        col = tablaContable.getColumnModel().getColumn(11);
        col.setPreferredWidth(100);
        col.setCellRenderer(renderizadorAlineacion);
        tablaContable.getColumnModel().removeColumn(tablaContable.getColumnModel().getColumn(12));
        modeloContable.addRow(filaVacia);
        this.setModel(modeloContable);
    }

    public void insertarFila(String[] fila) {
        fila[9] = "AUTOMÁTICO";
        modeloContable.addRow(fila);
    }

    public boolean eliminarFila(int fila) {
        boolean resultado = false;
        if (fila >= 0) {
            modeloContable.removeRow(fila);
            resultado = true;
        } else {
            resultado = false;
        }
        return resultado;
    }

    public void resetearTabla() {
        for (int i = this.modeloContable.getRowCount() - 1; i >= 0; i--) {
            this.eliminarFila(i);
        }
        insertarFila(filaVacia);
    }

    public String[][] convierteTabla(JTable tabla) {
        String[][] tablaConvertida = new String[tabla.getRowCount()][tabla.getColumnCount()];
        for (int i = 0; i <= tabla.getRowCount() - 1; i++) {
            for (int j = 0; j <= tabla.getColumnCount() - 1; j++) {
                tablaConvertida[i][j] = tabla.getValueAt(i, j).toString();
            }
        }
        return tablaConvertida;
    }

    public String[] leerPrimeraFila(JTable tabla) {
        String[] primeraFila = new String[13];
        for (int j = 0; j < tabla.getColumnCount(); j++) {
            primeraFila[j] = tabla.getValueAt(0, j).toString();
        }
        primeraFila[12] = "S";
        return primeraFila;
    }

    public void ordenarTabla(String[] fila) {
        for (int j = 0; j <= 11; j++) {
            modeloContable.setValueAt("", 0, j);
        }
        modeloContable.setValueAt("S", 0, 12);
    }

    public void setFilaActual(int filaActual) {
        this.filaActual = filaActual;
    }

    public int getFilaActual() {
        return filaActual;
    }

    public void setColumnaActual(int columnaActual) {
        this.columnaActual = columnaActual;
    }

    public int getColumnaActual() {
        return columnaActual;
    }

    public String valorDeCelda(int fila, int columna) {
        String resultado = "";
        resultado = modeloContable.getValueAt(fila, columna).toString();
        return resultado;
    }

    public boolean cargarCuenta(String niv1, String niv2, String niv3, String niv4, String niv5, int filaActual) throws SQLException {
        CCo021 co021 = new CCo021();
        boolean resultado = false;
        ResultSet rsCuenta = co021.buscarCuentaPorNiveles(niv1, niv2, niv3, niv4, niv5);
        if (rsCuenta.next()) {
            modeloContable.setValueAt(rsCuenta.getString("co021desc"), filaActual, 5);
            modeloContable.setValueAt("0", filaActual, 6);
            modeloContable.setValueAt("0", filaActual, 7);
            modeloContable.setValueAt("0", filaActual, 8);
            modeloContable.setValueAt("AUTOMÁTICO", filaActual, 9);
            if ((modeloContable.getValueAt(filaActual, 10).toString().equalsIgnoreCase("0.00") && modeloContable.getValueAt(filaActual, 11).toString().equalsIgnoreCase("0.00")) || (modeloContable.getValueAt(filaActual, 10).toString().equalsIgnoreCase("") && modeloContable.getValueAt(filaActual, 11).toString().equalsIgnoreCase(""))) {
                modeloContable.setValueAt("", filaActual, 9);
                modeloContable.setValueAt(numero.formatearDecimales(2, 0.00), filaActual, 10);
                modeloContable.setValueAt(numero.formatearDecimales(2, 0.00), filaActual, 11);
            }
            resultado = true;
        } else {
            resultado = false;
        }
        return resultado;

    }

    public boolean cargarDetallePorNoAsiento(String noas) throws SQLException, IOException {
        CCo100 co100 = new CCo100();
        CCo021 co021 = new CCo021();
        boolean resultado = false;
        ResultSet rsCuenta = co100.buscarDetallePorNumeroDeAsiento(noas);
        if (rsCuenta.next()) {
            resultado = true;
            rsCuenta.beforeFirst();
            while (rsCuenta.next()) {
                String[] fila = new String[13];
                fila[0] = rsCuenta.getString("co101niv1");
                fila[1] = rsCuenta.getString("co101niv2");
                fila[2] = rsCuenta.getString("co101niv3");
                fila[3] = rsCuenta.getString("co101niv4");
                fila[4] = rsCuenta.getString("co101niv5");
                fila[5] = co021.descripcion(fila[0], fila[1], fila[2], fila[3], fila[4]);
                fila[6] = rsCuenta.getString("co101cec1");
                fila[7] = rsCuenta.getString("co101cec2");
                fila[8] = rsCuenta.getString("co101cec3");
                fila[9] = rsCuenta.getString("co101desc");
                if (rsCuenta.getString("co101timo").equalsIgnoreCase("D")) {
                    fila[10] = numero.formatearDecimales(2, Double.parseDouble(rsCuenta.getString("co101valn")));
                    fila[11] = numero.formatearDecimales(2, 0.00);
                } else {
                    fila[10] = numero.formatearDecimales(2, 0.00);
                    fila[11] = numero.formatearDecimales(2, Double.parseDouble(rsCuenta.getString("co101valn").substring(1)));
                }
                fila[12] = "M";
                this.insertarFila(fila);
            }
        } else {
            resultado = false;
        }
        return resultado;
    }

    public void cagarDetallePorCodigoDco(String codigoDco, String[] valores) throws SQLException {
        CCalculos calculos = new CCalculos();
        CDco100 dco100 = new CDco100(codigoDco);
        ResultSet rsCuenta = dco100.buscarDetalleCuenta(codigoDco);
        while (rsCuenta.next()) {
            String[] fila = new String[13];
            fila[0] = rsCuenta.getString("dco101niv1");
            fila[1] = rsCuenta.getString("dco101niv2");
            fila[2] = rsCuenta.getString("dco101niv3");
            fila[3] = rsCuenta.getString("dco101niv4");
            fila[4] = rsCuenta.getString("dco101niv5");
            fila[5] = rsCuenta.getString("dco101decu");
            fila[6] = rsCuenta.getString("dco101cec1");
            fila[7] = rsCuenta.getString("dco101cec2");
            fila[8] = rsCuenta.getString("dco101cec3");
            fila[9] = "AUTOMÁTICO";
            if (rsCuenta.getString("dco101timo").equalsIgnoreCase("D")) {
                fila[10] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
                fila[11] = numero.formatearDecimales(2, 0.00);
            } else {
                fila[10] = numero.formatearDecimales(2, 0.00);
                fila[11] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
            }
            fila[12] = "N";
            this.insertarFila(fila);
        }
    }

    public void cagarDetallePorCodigoDco(String codigoDco, String[] valores, String tipoEntidad) throws SQLException {
        CCalculos calculos = new CCalculos();
        CDco100 dco100 = new CDco100(codigoDco);
        ResultSet rsCuenta = dco100.buscarDetalleCuenta(codigoDco, tipoEntidad);
        while (rsCuenta.next()) {
            String[] fila = new String[13];
            fila[0] = rsCuenta.getString("dco101niv1");
            fila[1] = rsCuenta.getString("dco101niv2");
            fila[2] = rsCuenta.getString("dco101niv3");
            fila[3] = rsCuenta.getString("dco101niv4");
            fila[4] = rsCuenta.getString("dco101niv5");
            fila[5] = rsCuenta.getString("dco101decu");
            fila[6] = rsCuenta.getString("dco101cec1");
            fila[7] = rsCuenta.getString("dco101cec2");
            fila[8] = rsCuenta.getString("dco101cec3");
            fila[9] = "AUTOMÁTICO";
            if (rsCuenta.getString("dco101timo").equalsIgnoreCase("D")) {
                fila[10] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
                fila[11] = numero.formatearDecimales(2, 0.00);
            } else {
                fila[10] = numero.formatearDecimales(2, 0.00);
                fila[11] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
            }
            fila[12] = "N";
            this.insertarFila(fila);
        }
    }

    public void cagarDetallePorCodigoDcoXCodigoAuxiliar(String codigoDco, String[] valores, String codigoAuxiliar) throws SQLException {
        CCalculos calculos = new CCalculos();
        CDco100 dco100 = new CDco100(codigoDco);
        ResultSet rsCuenta = dco100.buscarDetalleCuentaXCodigoAuxiliar(codigoDco, codigoAuxiliar);
        while (rsCuenta.next()) {
            String[] fila = new String[13];
            fila[0] = rsCuenta.getString("dco101niv1");
            fila[1] = rsCuenta.getString("dco101niv2");
            fila[2] = rsCuenta.getString("dco101niv3");
            fila[3] = rsCuenta.getString("dco101niv4");
            fila[4] = rsCuenta.getString("dco101niv5");
            fila[5] = rsCuenta.getString("dco101decu");
            fila[6] = rsCuenta.getString("dco101cec1");
            fila[7] = rsCuenta.getString("dco101cec2");
            fila[8] = rsCuenta.getString("dco101cec3");
            fila[9] = "AUTOMÁTICO";
            if (rsCuenta.getString("dco101timo").equalsIgnoreCase("D")) {
                fila[10] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
                fila[11] = numero.formatearDecimales(2, 0.00);
            } else {
                fila[10] = numero.formatearDecimales(2, 0.00);
                fila[11] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(rsCuenta.getString("dco101valo"), valores)));
            }
            fila[12] = "N";
            this.insertarFila(fila);
        }
    }

    public void cagarDetallePorCodigoDcoRetenciones(String codigoDco, String[] valores, String tipoEntidad) throws SQLException {
        CCalculos calculos = new CCalculos();
        CDco100 dco100 = new CDco100(codigoDco);
        ResultSet rsCuenta = dco100.buscarDetalleCuenta(codigoDco, tipoEntidad);
        while (rsCuenta.next()) {
            String codigoAuxiliar = rsCuenta.getString("dco101coax");
            if (!codigoAuxiliar.isEmpty()) {
                String[] fila = new String[13];
                fila[0] = rsCuenta.getString("dco101niv1");
                fila[1] = rsCuenta.getString("dco101niv2");
                fila[2] = rsCuenta.getString("dco101niv3");
                fila[3] = rsCuenta.getString("dco101niv4");
                fila[4] = rsCuenta.getString("dco101niv5");
                fila[5] = rsCuenta.getString("dco101decu");
                fila[6] = rsCuenta.getString("dco101cec1");
                fila[7] = rsCuenta.getString("dco101cec2");
                fila[8] = rsCuenta.getString("dco101cec3");
                fila[9] = "AUTOMÁTICO";
                String formula = rsCuenta.getString("dco101valo");
                CRt100 rt100 = new CRt100(codigoAuxiliar);
                formula = formula.replace("rt100porc", rt100.getPorcentaje());
                if (rsCuenta.getString("dco101timo").equalsIgnoreCase("D")) {
                    fila[10] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(formula, valores)));
                    fila[11] = numero.formatearDecimales(2, 0.00);
                } else {
                    fila[10] = numero.formatearDecimales(2, 0.00);
                    fila[11] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(formula, valores)));
                }
                fila[12] = "N";
                this.insertarFila(fila);
            } else {
                this.cagarDetallePorCodigoDcoRetencionesTotal(codigoDco, valores, tipoEntidad);
            }
        }
    }

    private void cagarDetallePorCodigoDcoRetencionesTotal(String codigoDco, String[] valores, String tipoEntidad) throws SQLException {
        CCalculos calculos = new CCalculos();
        CDco100 dco100 = new CDco100(codigoDco);
        ResultSet rsCuenta = dco100.buscarDetalleCuenta(codigoDco, tipoEntidad);
        while (rsCuenta.next()) {
            String codigoAuxiliar = rsCuenta.getString("dco101coax");
            if (codigoAuxiliar.isEmpty()) {
                String[] fila = new String[13];
                fila[0] = rsCuenta.getString("dco101niv1");
                fila[1] = rsCuenta.getString("dco101niv2");
                fila[2] = rsCuenta.getString("dco101niv3");
                fila[3] = rsCuenta.getString("dco101niv4");
                fila[4] = rsCuenta.getString("dco101niv5");
                fila[5] = rsCuenta.getString("dco101decu");
                fila[6] = rsCuenta.getString("dco101cec1");
                fila[7] = rsCuenta.getString("dco101cec2");
                fila[8] = rsCuenta.getString("dco101cec3");
                fila[9] = "AUTOMÁTICO";
                String formula = rsCuenta.getString("dco101valo");
                String[] valoresNuevos = new String[valores.length + 4];
                for (int i = 0; i <= valores.length - 1; i++) {
                    valoresNuevos[i] = valores[i];
                }
                valoresNuevos[valoresNuevos.length - 4] = "operacion1";
                valoresNuevos[valoresNuevos.length - 2] = "operacion2";
                if (this.modeloContable.getRowCount() == 0) {
                    valoresNuevos[valoresNuevos.length - 3] = "0.00";
                    valoresNuevos[valoresNuevos.length - 1] = "0.00";
                }
                if (this.modeloContable.getRowCount() == 2) {
                    valoresNuevos[valoresNuevos.length - 3] = this.getValueAt(1, 11).toString();
                    valoresNuevos[valoresNuevos.length - 1] = "0.00";
                } else if (this.modeloContable.getRowCount() == 3) {
                    valoresNuevos[valoresNuevos.length - 3] = this.getValueAt(1, 11).toString();
                    valoresNuevos[valoresNuevos.length - 1] = this.getValueAt(2, 11).toString();
                }
                if (rsCuenta.getString("dco101timo").equalsIgnoreCase("D")) {
                    fila[10] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(formula, valoresNuevos)));
                    fila[11] = numero.formatearDecimales(2, 0.00);
                } else {
                    fila[10] = numero.formatearDecimales(2, 0.00);
                    fila[11] = numero.formatearDecimales(2, Double.parseDouble(calculos.calcularFormula(formula, valoresNuevos)));
                }
                fila[12] = "N";
                this.insertarFila(fila);
            }
        }
    }

    public String sumaDebito() {
        Double debito = 0.00;
        for (int i = 1; i < modeloContable.getRowCount(); i++) {
            debito += Double.parseDouble(modeloContable.getValueAt(i, 10).toString());

        }
        return numero.formatearDecimales(2, debito);
    }

    public String sumaCredito() {
        Double credito = 0.00;
        for (int i = 1; i < modeloContable.getRowCount(); i++) {
            credito += Double.parseDouble(modeloContable.getValueAt(i, 11).toString());
        }
        return numero.formatearDecimales(2, credito);
    }

    public String sumaCreditoDebito() {
        Double credito = Double.parseDouble(this.sumaCredito()) * -1;
        Double debito = Double.parseDouble(this.sumaDebito());
        Double suma = debito + credito;
        return numero.formatearDecimales(2, suma);
    }

    public boolean validarCamposVacios() {
        boolean resultado = true;
        for (int i = 1; i < modeloContable.getRowCount(); i++) {
            for (int j = 0; j < modeloContable.getColumnCount(); j++) {
                if (modeloContable.getValueAt(i, j).toString().isEmpty()) {
                    resultado = false;
                }
            }
        }
        return resultado;
    }

    public void intercambiarDebitoCredito() {
        for (int i = 1; i < modeloContable.getRowCount(); i++) {
            String debito = modeloContable.getValueAt(i, 10).toString();
            String credito = modeloContable.getValueAt(i, 11).toString();
            modeloContable.setValueAt(credito, i, 10);
            modeloContable.setValueAt(debito, i, 11);
        }
    }

    public void actualizarDescripcionAsiento(String descripcionAsiento) {
        for (int i = 1; i < modeloContable.getRowCount(); i++) {
            modeloContable.setValueAt(descripcionAsiento.toUpperCase(), i, 9);
        }
    }
}

class modeloTablaContable extends DefaultTableModel {

    @Override
    public boolean isCellEditable(int row, int column) {
        boolean resultado = false;
        if (this.getValueAt(row, 12).toString().equalsIgnoreCase("S")) {
            if (column == 0 || column == 1 || column == 2 || column == 3 || column == 4 || column == 10 || column == 11) {
                resultado = true;
            }
        } else if (this.getValueAt(row, 12).toString().equalsIgnoreCase("M")) {
            if (column == 0 || column == 1 || column == 2 || column == 3 || column == 4 || column == 10 || column == 11) {
                resultado = true;
            }
        } else {
            if (column == 0 || column == 1 || column == 2 || column == 3 || column == 4 || column == 5 || column == 6 || column == 7 || column == 8 || column == 9 || column == 10 || column == 11) {
                resultado = false;
            }
        }
        return resultado;
    }
}
